home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / lib / yotpin / src / circle.c next >
Encoding:
C/C++ Source or Header  |  1995-08-26  |  3.5 KB  |  173 lines

  1. /*
  2. *    Yamana's Otomeza Plug-in Tool
  3. *        3点指定円
  4. *    
  5. *    1995.08.20
  6. *    1995.08.26    手ぶれんビ~搭載(^^;)
  7. *    
  8. */
  9. #include    "otome_pi.h"
  10. #include    "costbl.h"
  11.  
  12. const char longname[] = "DRAW  : 3点指定円";
  13. int            cnfg_max = 2;
  14. PI_CNFG        cnfg[] = {
  15.                 {"楕円      正円"    , 0,  1,  0,  0 },
  16.                 {"線の太さ"            , 1, 32,  1,  1 }
  17.             };
  18.  
  19. #define    USE_ENV        PI_SET_ENV
  20. #define    USE_TYPE    PI_EFFC_POLY
  21. #include    "otome_pi.c"
  22.  
  23. /* 手ぶれとする値 */
  24. #define        TEBURE        3
  25.  
  26. /*******************************************************/
  27.  
  28. POINT    Points[3];
  29.  
  30.  
  31. /* 3点の座標を得る */
  32. int get_Points()
  33. {
  34.     int ox,oy,i,j;
  35.     
  36.     if( WORD(g_para) < 3 )
  37.         return ERROR;
  38.     
  39.     memcpy( &Points[0], g_para+2, 2*2 );    /* 第1点 */
  40.     
  41.     /* 手ぶれによって点が接近している場合があるので補正する。*/
  42.     i = 0;
  43.     j = 0;
  44.     while( j<2)
  45.     {    do
  46.         {    i++;
  47.             ox = WORD( g_para+i*4+2 );
  48.             oy = WORD( g_para+i*4+4 );
  49.             
  50.         }while( abs(ox-Points[j].x)<=TEBURE
  51.              && abs(oy-Points[j].y)<=TEBURE    && i<WORD(g_para) );
  52.         
  53.         if( i >= WORD(g_para) )    return ERROR;
  54.         j++;
  55.         Points[j].x = ox;
  56.         Points[j].y = oy;
  57.     }
  58.     return NOERR;
  59. }
  60.  
  61. /*******************************************************/
  62.  
  63. int circle_3Points()
  64. {
  65.     char    tmp[2*2];
  66.     
  67.     EGB_bow( EgbPtr, &Points );
  68.     
  69.     /* 2点目と3点目を入れ替えて再実行するだけ */
  70.     memcpy( tmp,            &Points[1].x,    2*2 );
  71.     memcpy( &Points[1].x,    &Points[2].x,    2*2 );
  72.     memcpy( &Points[2].x,    tmp,            2*2 );
  73.     
  74.     EGB_bow( EgbPtr, &Points );
  75.     
  76.     return NOERR;
  77. }
  78.  
  79. /* 128角形を楕円変形し回転させる */
  80. /* 256角形にしても速度差はほとんどないが、誤差が拡大されてしまう */
  81. #define    EN_P    128
  82.  
  83. int circle_slant()
  84. {
  85.     register int     x,y;
  86.     int     t,ox,oy,step;
  87.     int     rx,ry,r,rby;
  88.     int     rsin,rcos;
  89.     char    *para,*p;
  90.     
  91.     if( (para=(char*)PI_MALLOC( 2+ EN_P*4 ))==NULL )
  92.         return PI_ERROR_NO_MEMORY;
  93.     
  94. #ifdef    DEBUG
  95.     printf("(%d,%d)-(%d,%d)-(%d,%d)",
  96.         Points[0].x,Points[0].y,
  97.         Points[1].x,Points[1].y,
  98.         Points[2].x,Points[2].y        );
  99. #endif
  100.     
  101.     /* 最初の2点間の距離÷2を楕円の1つ目の軸長とする */
  102.     x = (Points[0].x - Points[1].x);
  103.     y = (Points[0].y - Points[1].y);
  104.     rx = sqrt( x*x + y*y )/2;
  105.     
  106.     /* 中心点 */
  107.     ox = (Points[0].x + Points[1].x)/ 2 ;
  108.     oy = (Points[0].y + Points[1].y)/ 2 ;
  109.     
  110.     /* 中点と3点目の距離を楕円の2つ目の軸長とする */
  111.     x = (Points[2].x - ox);
  112.     y = (Points[2].y - oy);
  113.     ry = sqrt( x*x + y*y );
  114.     
  115.     rby = 256*ry/rx;
  116.     
  117.     /* 回転角 */
  118.     rsin = ((oy - Points[1].y)<<8 )/ ry;
  119.     rcos = ((ox - Points[1].x)<<8 )/ ry;
  120.     r = ry;
  121.     
  122.     step = 256 / EN_P;
  123.     WORD( para ) = EN_P+1 ;
  124.     p = para+2;
  125.     for( t=0 ; t<= 256 ; t+=step,p+=4 )
  126.     {
  127.         x = (r * cos256( t ) );
  128.         y = (r * sin256( t ) * rby + 0x80 >>8 );    /* 四捨五入 */
  129.         
  130.         WORD( p   ) = ox + ((x*rcos - y*rsin) >>16) ;
  131.         WORD( p+2 ) = oy + ((x*rsin + y*rcos) >>16) ;
  132.     }
  133.     
  134.     EGB_connect( EgbPtr, para );
  135.     
  136.     PI_FREE( para );
  137.     
  138.     return NOERR;
  139. }
  140.  
  141. /*************************************/
  142.  
  143. int APL_exec()
  144. {
  145.     int     mode,pen,ret;
  146.     
  147.     mode = cnfg[0].val;
  148.     pen  = cnfg[1].val;
  149.     
  150.     if( get_Points() )    return ERROR;
  151.     
  152.     EGB_writePage( EgbPtr, PI_PAGE );
  153.     EGB_writeMode( EgbPtr, EGB_PSET );
  154.     
  155.     /* タイル指定を有効に */
  156.     if( PI_TILEFLG )
  157.     {    EGB_tilePattern( EgbPtr, EGB_FORECOL,
  158.                     PI_TILE_X, PI_TILE_Y, PI_TILE_PAT );
  159.         EGB_paintMode( EgbPtr, EGB_PAINT_TILE );
  160.     }else
  161.     {    EGB_color( EgbPtr, EGB_FORECOL,  PI_FORECOL );
  162.         EGB_paintMode( EgbPtr, EGB_PAINT_BETA );
  163.     }
  164.     EGB_penSize( EgbPtr, pen );
  165.     
  166.     
  167.          if( mode==0 )    return circle_slant();
  168.     else if( mode==1 )    return circle_3Points();
  169.     else                 return ERROR;
  170.     
  171. }
  172.  
  173.